package com.xc.round2Assessment.petStore.shop;

import com.xc.round2Assessment.petStore.exception.AnimalNotFoundException;
import com.xc.round2Assessment.petStore.exception.InsufficientBalanceException;
import com.xc.round2Assessment.petStore.pet.facade.StrategyFacade;
import com.xc.round2Assessment.petStore.pet.strategy.AnimalStrategy;
import com.xc.round2Assessment.petStore.pet.strategy.BirdStrategy;
import com.xc.round2Assessment.petStore.pojo.Customer;
import net.minidev.json.JSONUtil;

import java.time.LocalDate;
import java.util.*;

/**
 * @author Xc
 * @version 1.0
 * 假设每只动物都有四分之一的利润, 方便后面的计算
 */
public class MyAnimalShop implements AnimalShop{

    private double account; //余额
    private Map<AnimalStrategy, Integer> animalMap;
    private Map<LocalDate, List<Customer>> customerMap;

    public MyAnimalShop() {
        this.account = 500;
        animalMap = new HashMap<>();
        customerMap = new HashMap<>();
    }

    public MyAnimalShop(Integer account) {
        this.account = account;
        animalMap = new HashMap<>();
        customerMap = new HashMap<>();
    }

    /**
     * @param choice 要购买动物的种类
     * 调用门面模式完成购买, 返回的参数是购买所用的钱
     * 该方法是宠物商店进货(购买动物)的方法
     */
    @Override
    public void buyAnimals(int choice) {
        AnimalStrategy animal = StrategyFacade.buy(choice);
        if (account - animal.getPrice() < 0) {
            System.out.println("=============== Warning ===============");
            System.out.println("Now you hava only " + getAccount() + " yuan");
            System.out.println("The animal you want to buy is " + animal.getName() + ", it worths " + animal.getPrice() + " yuan~");
            System.out.println("[choice : 0 bird - 300 yuan, 1 cat - 200 yuan, 2 dog - 100 yuan]");
            System.out.println("========== That'll be an exception below ==========");
            throw new InsufficientBalanceException("店内余额不足以购买" + animal.getName() + ", 请换一种动物购买~");
        }
        account -= animal.getPrice(); // 更新商店余额
        // 更新宠物列表的状态
        if (!animalMap.containsKey(animal)) {
            animalMap.put(animal, 1);
        } else {
            animalMap.put(animal, animalMap.get(animal) + 1);
        }
    }

    @Override
    public void treatCustom(Customer customer) {
        // 更新最新的到店时间
        if (!customerMap.containsKey(customer.getLastedArrTime())) {
            List<Customer> cusList = new ArrayList<>();
            cusList.add(customer);
            customerMap.put(customer.getLastedArrTime(), cusList);
        } else {
            List<Customer> cusList = customerMap.get(customer.getLastedArrTime());
            cusList.add(customer);
            customerMap.put(customer.getLastedArrTime(), cusList);
        }

        customer.setArrNums(customer.getArrNums() + 1);

        // 顾客购买宠物
        AnimalStrategy animal = StrategyFacade.buy(customer.getWantedType());
        if (!animalMap.containsKey(animal)) {
            throw new AnimalNotFoundException("商店中目前没有" + animal.getName() + ", 先购买别的动物吧~");
        } else {
            System.out.println("顾客 " + customer.getName() + " 成功购买了一只 " + animal.getName());
            System.out.println("\n======== 展示宠物的信息 ========");
            System.out.println(animal.toString());
            // 假设每只动物都有四分之一的利润, 方便后面的计算
            account += animal.getPrice() * 1.25;
            animalMap.put(animal, animalMap.get(animal) - 1);
        }
    }

    /**
     * @param time
     * @return 返回的是当天的利润
     */
    @Override
    public double close(LocalDate time) {
        System.out.println("\n========== 宠物店歇业啦 ==========");
        // 输出当天光顾的客户的列表信息
        System.out.println(time.getYear() + "年" + time.getMonthValue() + "月" + time.getDayOfMonth() + "日 光顾过宠物店的顾客有下面这些: ");
        double profit = 0; // 利润
        List<Customer> customers = customerMap.get(time);
        for (Customer customer : customers) {
            System.out.println(customer.toString());
            profit += StrategyFacade.buy(customer.getWantedType()).getPrice() * 0.25;
        }
        System.out.println("该日的利润为: " + profit);
        return profit;
    }

    // 展示店内目前有的动物
    public void showAnimals() {
        System.out.println("\n========== 展示目前店内拥有宠物的情况 ==========");
        Map<AnimalStrategy, Integer> animalMap = getAnimalMap();
        if (animalMap.size() == 0) {
            System.out.println("店内目前没有宠物~");
            return;
        }
        System.out.println("店内目前有 : ");
        Set<Map.Entry<AnimalStrategy, Integer>> entries = animalMap.entrySet();
        for (Map.Entry<AnimalStrategy, Integer> entry : entries) {
            System.out.println(entry.getValue() + "只" + entry.getKey().getName());
        }
    }

    public double getAccount() {
        return account;
    }

    public void setAccount(double account) {
        this.account = account;
    }

    public Map<AnimalStrategy, Integer> getAnimalMap() {
        return animalMap;
    }

    public void setAnimalMap(Map<AnimalStrategy, Integer> animalMap) {
        this.animalMap = animalMap;
    }

    public Map<LocalDate, List<Customer>> getCustomerMap() {
        return customerMap;
    }

    public void setCustomerMap(Map<LocalDate, List<Customer>> customerMap) {
        this.customerMap = customerMap;
    }
}
